/*
 * Copyright (C) 2022 VYAGOO TECHNOLOGY Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef AC107_ACCESSORY_IMPL_LINUX_H
#define AC107_ACCESSORY_IMPL_LINUX_H

// #include "audio_accessory_if.h"
#include "securec.h"
#include <linux/types.h>
#include "audio_host.h"
#include "audio_control.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */

/*** AC107 Codec Register Define***/

//Chip Reset
#define CHIP_AUDIO_RST      0x00

//Power Control
#define PWR_CTRL1           0x01
#define PWR_CTRL2           0x02

//PLL Configure Control
#define PLL_CTRL1           0x10
#define PLL_CTRL2           0x11
#define PLL_CTRL3           0x12
#define PLL_CTRL4           0x13
#define PLL_CTRL5           0x14
#define PLL_CTRL6           0x16
#define PLL_CTRL7           0x17
#define PLL_LOCK_CTRL       0x18

//System Clock Control
#define SYSCLK_CTRL         0x20
#define MOD_CLK_EN          0x21
#define MOD_RST_CTRL        0x22

//I2S Common Control
#define I2S_CTRL            0x30
#define I2S_BCLK_CTRL       0x31
#define I2S_LRCK_CTRL1      0x32
#define I2S_LRCK_CTRL2      0x33
#define I2S_FMT_CTRL1       0x34
#define I2S_FMT_CTRL2       0x35
#define I2S_FMT_CTRL3       0x36

//I2S TX Control
#define I2S_TX_CTRL1        0x38
#define I2S_TX_CTRL2        0x39
#define I2S_TX_CTRL3        0x3A
#define I2S_TX_CHMP_CTRL1   0x3C
#define I2S_TX_CHMP_CTRL2   0x3D

//I2S RX Control
#define I2S_RX_CTRL1        0x50
#define I2S_RX_CTRL2        0x51
#define I2S_RX_CTRL3        0x52
#define I2S_RX_CHMP_CTRL1   0x54
#define I2S_RX_CHMP_CTRL2   0x55

//PDM Control
#define PDM_CTRL            0x59

//ADC Common Control
#define ADC_SPRC            0x60
#define ADC_DIG_EN          0x61
#define DMIC_EN             0x62
#define HPF_EN              0x66

//ADC Digital Channel Volume Control
#define ADC1_DVOL_CTRL      0x70
#define ADC2_DVOL_CTRL      0x71

//ADC Digital Mixer Source and Gain Control
#define ADC1_DMIX_SRC       0x76
#define ADC2_DMIX_SRC       0x77

//ADC Digital Debug Control
#define ADC_DIG_DEBUG       0x7F

//IO Function and Drive Control
#define ADC_ANA_DEBUG1      0x80
#define ADC_ANA_DEBUG2      0x81
#define I2S_PADDRV_CTRL     0x82

//ADC1 Analog Control
#define ANA_ADC1_CTRL1      0xA0
#define ANA_ADC1_CTRL2      0xA1
#define ANA_ADC1_CTRL3      0xA2
#define ANA_ADC1_CTRL4      0xA3
#define ANA_ADC1_CTRL5      0xA4

//ADC2 Analog Control
#define ANA_ADC2_CTRL1      0xA5
#define ANA_ADC2_CTRL2      0xA6
#define ANA_ADC2_CTRL3      0xA7
#define ANA_ADC2_CTRL4      0xA8
#define ANA_ADC2_CTRL5      0xA9

//ADC Dither Control
#define ADC_DITHER_CTRL     0xAA

#define AC107_MAX_REG       ADC_DITHER_CTRL

/*** AC107 Codec Register Bit Define***/

/* PWR_CTRL1 */
#define VREF_ENABLE         7
#define VREF_LPMODE         6
#define VREF_FSU_DISABLE    5
#define VREF_RESCTRL        3
#define IGEN_TRIM           0

/* PWR_CTRL2 */
#define VREF_SEL            7
#define MICBIAS2_EN         6
#define MICBIAS2_VCTRL      4
#define MICBIAS1_EN         2
#define MICBIAS1_VCTRL      0


/*PLL_CTRL1*/
#define PLL_IBIAS           4
#define PLL_NDET            3
#define PLL_LOCKED_STATUS   2
#define PLL_COM_EN          1
#define PLL_EN              0

/*PLL_CTRL2*/
#define PLL_PREDIV2         5
#define PLL_PREDIV1         0

/*PLL_CTRL3*/
#define PLL_LOOPDIV_MSB     0

/*PLL_CTRL4*/
#define PLL_LOOPDIV_LSB     0

/*PLL_CTRL5*/
#define PLL_POSTDIV2        5
#define PLL_POSTDIV1        0

/*PLL_CTRL6*/
#define PLL_LDO             6
#define PLL_CP              0

/*PLL_CTRL7*/
#define PLL_CAP             6
#define PLL_RES             4

/*PLL_LOCK_CTRL*/
#define SYSCLK_HOLD_TIME    4
#define LOCK_LEVEL1         2
#define LOCK_LEVEL2         1
#define PLL_LOCK_EN         0


/* SYSCLK_CTRL */
#define PLLCLK_EN           7
#define PLLCLK_SRC          4
#define SYSCLK_SRC          2
#define SYSCLK_EN           0

/* MOD_CLK_EN & MOD_RST_CTRL */
#define I2S_RST             4
#define ADC_ANALOG          2
#define ADC_DIGITAL         1
#define I2S                 0


/* I2S_CTRL */
#define BCLK_IOEN           7
#define LRCK_IOEN           6
#define MCLK_IOEN           5
#define SDO_EN              4
#define TXEN                2
#define RXEN                1
#define GEN                 0

/* I2S_BCLK_CTRL */
#define EDGE_TRANSFER       5
#define BCLK_POLARITY       4
#define BCLKDIV             0

/* I2S_LRCK_CTRL1 */
#define LRCK_POLARITY       4
#define LRCK_PERIODH        0

/* I2S_LRCK_CTRL2 */
#define LRCK_PERIODL        0

/* I2S_FMT_CTRL1 */
#define ENCD_FMT            7
#define ENCD_SEL            6
#define MODE_SEL            4
#define TX_OFFSET           2
#define TX_SLOT_HIZ         1
#define TX_STATE            0

/* I2S_FMT_CTRL2 */
#define SLOT_WIDTH_SEL      4
#define SAMPLE_RESOLUTION   0

/* I2S_FMT_CTRL3 */
#define TX_MLS              7
#define SEXT                5
#define SDOUT_MUTE          3
#define LRCK_WIDTH          2
#define TX_PDM              0


/* I2S_TX_CTRL1 */
#define TX_CHSEL            0

/* I2S_TX_CTRL2 */
#define TX_CH8_EN           7
#define TX_CH7_EN           6
#define TX_CH6_EN           5
#define TX_CH5_EN           4
#define TX_CH4_EN           3
#define TX_CH3_EN           2
#define TX_CH2_EN           1
#define TX_CH1_EN           0

/* I2S_TX_CTRL3 */
#define TX_CH16_EN          7
#define TX_CH15_EN          6
#define TX_CH14_EN          5
#define TX_CH13_EN          4
#define TX_CH12_EN          3
#define TX_CH11_EN          2
#define TX_CH10_EN          1
#define TX_CH9_EN           0

/*  I2S_TX_CHMP_CTRL1 */
#define TX_CH8_MAP          7
#define TX_CH7_MAP          6
#define TX_CH6_MAP          5
#define TX_CH5_MAP          4
#define TX_CH4_MAP          3
#define TX_CH3_MAP          2
#define TX_CH2_MAP          1
#define TX_CH1_MAP          0

/*  I2S_TX_CHMP_CTRL2 */
#define TX_CH16_MAP         7
#define TX_CH15_MAP         6
#define TX_CH14_MAP         5
#define TX_CH13_MAP         4
#define TX_CH12_MAP         3
#define TX_CH11_MAP         2
#define TX_CH10_MAP         1
#define TX_CH9_MAP          0


/* I2S_RX_CTRL1 */
#define RX_CHSEL            0

/* I2S_RX_CTRL2 */
#define RX_CH8_EN           7
#define RX_CH7_EN           6
#define RX_CH6_EN           5
#define RX_CH5_EN           4
#define RX_CH4_EN           3
#define RX_CH3_EN           2
#define RX_CH2_EN           1
#define RX_CH1_EN           0

/* I2S_RX_CTRL3 */
#define RX_CH16_EN          7
#define RX_CH15_EN          6
#define RX_CH14_EN          5
#define RX_CH13_EN          4
#define RX_CH12_EN          3
#define RX_CH11_EN          2
#define RX_CH10_EN          1
#define RX_CH9_EN           0

/*  I2S_RX_CHMP_CTRL1 */
#define RX_CH8_MAP          7
#define RX_CH7_MAP          6
#define RX_CH6_MAP          5
#define RX_CH5_MAP          4
#define RX_CH4_MAP          3
#define RX_CH3_MAP          2
#define RX_CH2_MAP          1
#define RX_CH1_MAP          0

/*  I2S_RX_CHMP_CTRL2 */
#define RX_CH16_MAP         7
#define RX_CH15_MAP         6
#define RX_CH14_MAP         5
#define RX_CH13_MAP         4
#define RX_CH12_MAP         3
#define RX_CH11_MAP         2
#define RX_CH10_MAP         1
#define RX_CH9_MAP          0


/* PDM_CTRL */
#define PDM_TIMING          1
#define PDM_EN              0


/*ADC_SPRC*/
#define ADC_FS_I2S          0

/* ADC_DIG_EN */
#define REQ_WIDTH           4
#define REQ_EN              3
#define DG_EN               2
#define ENAD2               1
#define ENAD1               0

/* DMIC_EN */
#define DIG_MIC_EN          0

/* HPF_EN */
#define DIG_ADC2_HPF_EN     1
#define DIG_ADC1_HPF_EN     0

/* ADC1_DMIX_SRC */
#define ADC1_ADC2_DMXL_GC   3
#define ADC1_ADC1_DMXL_GC   2
#define ADC1_ADC2_DMXL_SRC  1
#define ADC1_ADC1_DMXL_SRC  0

/* ADC2_DMIX_SRC */
#define ADC2_ADC2_DMXL_GC   3
#define ADC2_ADC1_DMXL_GC   2
#define ADC2_ADC2_DMXL_SRC  1
#define ADC2_ADC1_DMXL_SRC  0


/* ADC_DIG_DEBUG */
#define I2S_LPB_DEBUG       3
#define ADC_PTN_SEL         0


/* ADC_ANA_DEBUG1 */
#define DMIC_CLK_PAD_SEL    4
#define DMIC_DAT_PAD_SEL    0

/* ADC_ANA_DEBUG2 */
#define DEV_ID1_PAD_SEL     4
#define DEV_ID0_PAD_SEL     0

/* I2S_PADDRV_CTRL */
#define MCLK_DRV            6
#define BCLK_DRV            4
#define LRCK_DRV            2
#define SDOUT_DRV           0


/* ANA_ADC1_CTRL1 */
#define RX1_PGA_OI_CTRL     5
#define RX1_PGA_AMP_IB_SEL  2
#define RX1_PGA_IN_VCM_CTRL 0

/* ANA_ADC1_CTRL2 */
#define RX1_PGA_OI_NM_CTRL      3
#define RX1_PGA_NMAMP_IB_SEL    0

/* ANA_ADC1_CTRL3 */
#define RX1_PGA_CTRL_RCM    5
#define RX1_PGA_GAIN_CTRL   0

/* ANA_ADC1_CTRL4 */
#define RX1_DSM_OTA_IB_SEL  5
#define RX1_DSM_COMP_IB_SEL 2
#define RX1_DSM_OTA_CTRL    0

/* ANA_ADC1_CTRL5 */
#define RX1_GLOBAL_EN       6
#define RX1_DSM_DISABLE     5
#define RX1_DSM_DEMOFF      4
#define RX1_SEL_OUT_EDGE    3
#define RX1_DSM_VRP_LPMODE  2
#define RX1_DSM_VRP_OUTCTRL 0


/* ANA_ADC2_CTRL1 */
#define RX2_PGA_OI_CTRL     5
#define RX2_PGA_AMP_IB_SEL  2
#define RX2_PGA_IN_VCM_CTRL 0

/* ANA_ADC2_CTRL2 */
#define RX2_PGA_OI_NM_CTRL      3
#define RX2_PGA_NMAMP_IB_SEL    0

/* ANA_ADC2_CTRL3 */
#define RX2_PGA_CTRL_RCM    5
#define RX2_PGA_GAIN_CTRL   0

/* ANA_ADC2_CTRL4 */
#define RX2_DSM_OTA_IB_SEL  5
#define RX2_DSM_COMP_IB_SEL 2
#define RX2_DSM_OTA_CTRL    0

/* ANA_ADC2_CTRL5 */
#define RX2_GLOBAL_EN       6
#define RX2_DSM_DISABLE     5
#define RX2_DSM_DEMOFF      4
#define RX2_SEL_OUT_EDGE    3
#define RX2_DSM_VRP_LPMODE  2
#define RX2_DSM_VRP_OUTCTRL 0


/* ADC_DITHER_CTRL */
#define DSM_DITHER_CTRL     4
#define DSM_DITHER_EN       3
#define DSM_DITHER_LVL      0



/*** Some Config Value ***/

//PLLCLK_SRC
#define PLLCLK_SRC_MCLK     0
#define PLLCLK_SRC_BCLK     1
#define PLLCLK_SRC_PDMCLK   2

//SYSCLK_SRC
#define SYSCLK_SRC_MCLK     0
#define SYSCLK_SRC_BCLK     1
#define SYSCLK_SRC_PLL      2

//I2S BCLK POLARITY Control
#define BCLK_NORMAL_DRIVE_N_SAMPLE_P    0
#define BCLK_INVERT_DRIVE_P_SAMPLE_N    1

//I2S LRCK POLARITY Control
#define    LRCK_LEFT_LOW_RIGHT_HIGH     0
#define LRCK_LEFT_HIGH_RIGHT_LOW        1

//I2S Format Selection
#define PCM_FORMAT                      0
#define LEFT_JUSTIFIED_FORMAT           1
#define RIGHT_JUSTIFIED_FORMAT          2

//I2S Sign Extend in slot
#define ZERO_OR_AUDIIO_GAIN_PADDING_LSB 0
#define SIGN_EXTENSION_MSB              1
#define TRANSFER_ZERO_AFTER             3

//ADC Digital Debug Control
#define ADC_PTN_NORMAL                  0
#define ADC_PTN_0x5A5A5A                1
#define ADC_PTN_0x123456                2
#define ADC_PTN_ZERO                    3
#define ADC_PTN_I2S_RX_DATA             4

//ADC PGA GAIN Control
#define ADC_PGA_GAIN_MINUS_6dB          0
#define ADC_PGA_GAIN_0dB                1
#define ADC_PGA_GAIN_3dB                4
#define ADC_PGA_GAIN_4dB                5
#define ADC_PGA_GAIN_5dB                6
#define ADC_PGA_GAIN_6dB                7
#define ADC_PGA_GAIN_7dB                8
#define ADC_PGA_GAIN_8dB                9
#define ADC_PGA_GAIN_9dB                10
#define ADC_PGA_GAIN_10dB               11
#define ADC_PGA_GAIN_11dB               12
#define ADC_PGA_GAIN_12dB               13
#define ADC_PGA_GAIN_13dB               14
#define ADC_PGA_GAIN_14dB               15
#define ADC_PGA_GAIN_15dB               16
#define ADC_PGA_GAIN_16dB               17
#define ADC_PGA_GAIN_17dB               18
#define ADC_PGA_GAIN_18dB               19
#define ADC_PGA_GAIN_19dB               20
#define ADC_PGA_GAIN_20dB               21
#define ADC_PGA_GAIN_21dB               22
#define ADC_PGA_GAIN_22dB               23
#define ADC_PGA_GAIN_23dB               24
#define ADC_PGA_GAIN_24dB               25
#define ADC_PGA_GAIN_25dB               26
#define ADC_PGA_GAIN_26dB               27
#define ADC_PGA_GAIN_27dB               28
#define ADC_PGA_GAIN_28dB               29
#define ADC_PGA_GAIN_29dB               30
#define ADC_PGA_GAIN_30dB               31

int32_t Ac107DeviceInit(struct AudioCard *audioCard);
int32_t Ac107DeviceReadReg(uint32_t reg, uint32_t *value);
int32_t Ac107DeviceWriteReg(uint32_t reg, uint32_t value);
int32_t Ac107DaiDeviceInit(struct AudioCard *card, const struct DaiDevice *device);
int32_t Ac107DaiStartup(const struct AudioCard *card, const struct DaiDevice *device);
int32_t Ac107DaiHwParams(const struct AudioCard *card, const struct AudioPcmHwParams *param);
int32_t Ac107DaiTrigger(const struct AudioCard *card, int cmd, const struct DaiDevice *dai);

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif

#endif /* AC107_ACCESSORY_IMPL_LINUX_H */
